/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.jxtafileshare;

import java.io.StringWriter;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URI;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import net.jxta.discovery.DiscoveryService;
import net.jxta.document.Advertisement;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Element;
import net.jxta.document.MimeMediaType;
import net.jxta.document.StructuredDocument;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.StructuredTextDocument;
import net.jxta.document.TextElement;
import net.jxta.endpoint.*;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.ID;
import net.jxta.id.IDFactory;
import net.jxta.impl.protocol.*;
import net.jxta.protocol.*;
import net.jxta.credential.*;
import net.jxta.discovery.DiscoveryEvent;
import net.jxta.discovery.DiscoveryListener;
import net.jxta.membership.*;
import net.jxta.peergroup.PeerGroup;
import net.jxta.peergroup.PeerGroupID;
import net.jxta.platform.NetworkManager;
/**
 *
 * @author Danny
 */
public class FindGroup implements DiscoveryListener{
    private PeerGroup myNetPeerGroup = null,
                      myDiscoveredPeerGroup = null;
    private transient NetworkManager manager = null;
    private PeerGroupAdvertisement myPeerGroupAdvertisement = null;
    private final static String name = "MyGroup";

    public FindGroup(NetworkManager manager) {
        this.manager = manager;
        if(!(manager == null)) {
            myNetPeerGroup = manager.getNetPeerGroup();
        } else {
            System.out.println("Network Manager does not exist!");
            System.exit(-1);
        }

        myDiscoveredPeerGroup = this.discoverPeerGroup(myNetPeerGroup, name);
        if(myDiscoveredPeerGroup != null) {
            System.out.println("Peer Group Found");
            this.joinGroup(myDiscoveredPeerGroup);
        }
        System.out.println("Peer Group Joined");
        this.printXmlAdvertisement("XML Advertisement for" +
                "Peer Group Advertisement",
                myDiscoveredPeerGroup.getPeerGroupAdvertisement());
    }

    private PeerGroup discoverPeerGroup(PeerGroup myNetPeerGroup,
                                    String name) {
        PeerGroup localPeerGroup;
        DiscoveryService myNetPeerGroupDiscoveryService = null;
        if(myNetPeerGroup != null) {
            myNetPeerGroupDiscoveryService =
                    myNetPeerGroup.getDiscoveryService();
        } else {
            System.out.println("Net Peer Group is null");
            System.exit(-1);
        }
        boolean isGroupFound = false;
        Enumeration localPeerGroupAdvertisementEnumeration = null;
        System.out.println("Trying to find advertisement...");
        while(!isGroupFound) {
            try {
                localPeerGroupAdvertisementEnumeration =
                        myNetPeerGroupDiscoveryService.
                        getLocalAdvertisements(DiscoveryService.GROUP, "Name", name);
            } catch(java.io.IOException e) {
                System.out.println("Can't discover local adv");
            }
            if (localPeerGroupAdvertisementEnumeration != null) {
                System.out.println("Found local advertisement");
                while(localPeerGroupAdvertisementEnumeration.hasMoreElements()) {
                    PeerGroupAdvertisement pgAdv = null;
                    pgAdv = (PeerGroupAdvertisement)
                            localPeerGroupAdvertisementEnumeration.
                            nextElement();
                    if(pgAdv.getName().equals(name)) {
                        myPeerGroupAdvertisement = pgAdv;
                        isGroupFound = true;
                        break;
                    }
                }
            }
            myNetPeerGroupDiscoveryService.getRemoteAdvertisements(null, DiscoveryService.GROUP, "Name",
                                                            name, 1, null);
            if(myPeerGroupAdvertisement != null) {
                isGroupFound = true;
            }
        }
        try {
            localPeerGroup = myNetPeerGroup.newGroup(myPeerGroupAdvertisement);
        } catch(net.jxta.exception.PeerGroupException e) {
            e.printStackTrace();
            return null;
        }
        return localPeerGroup;
    }

    void joinGroup(PeerGroup myLocalGroup) {
        StructuredDocument myCredentials = null;
        try {
            AuthenticationCredential myAuthenticationCredential =
                    new AuthenticationCredential(myLocalGroup, null, myCredentials);
            MembershipService myMembershipService =
                    myLocalGroup.getMembershipService();
            net.jxta.membership.Authenticator myAuthenticator =
                    myMembershipService.apply(myAuthenticationCredential);
            if(!myAuthenticator.isReadyForJoin()) {
                System.out.println("Authenticator is not complete");
                return;
            }
        } catch(Exception e) {
            System.out.println("Authentication failed - group not joined");
            e.printStackTrace();
            System.exit(-1);
        }
    }

    public void discoveryEvent(DiscoveryEvent ev) {
        Enumeration remotePeerGroupAdvertisementEnumeration = null;
        PeerGroup remotePeerGroup;

        DiscoveryResponseMsg myMessage = ev.getResponse();
        remotePeerGroupAdvertisementEnumeration = myMessage.getResponses();
        if(remotePeerGroupAdvertisementEnumeration != null) {
            System.out.println("Found remote advertisements!");
            while(remotePeerGroupAdvertisementEnumeration.hasMoreElements()) {
                PeerGroupAdvertisement pgAdv = null;
                pgAdv = (PeerGroupAdvertisement)
                        remotePeerGroupAdvertisementEnumeration.
                        nextElement();
                if(pgAdv.getName().equals(name)) {
                    myPeerGroupAdvertisement = pgAdv;
                }
            }
        }
    }

    private void printXmlAdvertisement(String title, Advertisement adv) {
        String separator = "";
        for(int i = 0; i < title.length() + 4; i++) {
            separator = separator + "-";
        }
        System.out.println(separator);
        System.out.println("| " + title + " |");
        System.out.println(separator);

        System.out.println(adv.toString());

        System.out.println(separator);
    }

    public PeerGroup getDiscoveredPeerGroup() {
        if(myDiscoveredPeerGroup != null) {
            return myDiscoveredPeerGroup;
        } else {
            System.out.println("Warning: Peer group is null");
            return null;
        }
    }
}
